/*	--- 迭代器 --- 


#	提供一种方法【顺序访问】一个【聚合对象】中的【各个元素】，而又【不需要暴露】该【对象的内部表示】。

================================================================

                                
【迭代器模式】（Iterator）实际上在【Java的集合类】中已经广泛使用了。

我们以List为例，要遍历ArrayList，即使我们知道【它的内部】存储了【一个Object[]数组】，也不应该【直接使用】数组索引去【遍历】，因为这样需要了解【集合内部的存储结构】。

如果使用【Iterator遍历】，那么，【ArrayList 和 LinkedList】 都可以以一种【统一的接口】来遍历： */
List<String> list = ...;

for (Iterator<String> it = list.iterator(); it.hasNext()) {
	String s= it.next();
}


/*
实际上，因为【Iterator模式】十分有用

因此，Java允许我们【直接】把任何【支持Iterator的集合对象】用【foreach循环】写出来： */
List<String> list = ...;

for (String s : list) {
	// ...
}


/*
然后由【Java编译器】完成【Iterator模式】的【所有循环代码】。

虽然我们对【如何使用Iterator】有了一定了解，

Q: 但如何实现一个【Iterator模式】呢？
A: 我们以一个【自定义的集合】为例，通过【Iterator模式】实现【倒序遍历】： */
public class ReverseArrayCollection<T> implements Iterable<T> {
	// 以【数组Array】形式,持有集合(容器Collection)
	private T[] array;

	public ReverseArrayCollection(T... objs) { // init
		this.array = Arrays.copyOfRange(objs, 0, objs.length);
		/* Object... objs  参数灵活化,可以实现传入
			test();
			test("1");
			test("1", "2");
			test("1", "2", "3");
		*/
	}

	public Iterator<T> iterator() {
		return ???;
	}
}


/*
实现【Iterator模式】的关键是【返回一个Iterator对象】，该【对象】知道【集合的内部结构】，因为它可以实现【倒序遍历】。

我们使用【Java的内部类】实现【这个Iterator】： */
public class ReverseArrayCollection<T> implements Iterable<T> {
	private T[] array; // genericity array

	// 1. init
	public ReverseArayCollection(T... objs) { 
		this.array = Arrays.copyOfRange(objs, 0, objs.length);
	}

	// 2. Instance_Iterator
	public Iterator<T> iterator() { 
		return new ReverseIterator(); // return ReverseIterator
	}

	// 2.1.  class_Iterator
	class ReverseIterator implements Iterator<T> {

		int index;

		// 2.1.1 Init
		public ReverseIterator() { 
			this.index = ReverseArrayCollection.this.array.length;
				// 隐含地持有一个ReverseIterator所在对象ReverseArrayCollection的this引用
		}

		// 2.1.2 Judge
		public boolean hasNext() {
			// 如果index > 0, 那么可以移动到下一个元素(倒序:往上一个元素移动)
			return index > 0;
		}

		// 2.1.3 Action
		public T next() {
			// 倒序: 将index移动到"上一个元素"并返回
			index--;
			return array[index];
		}
	}
}


/*
【使用内部类】的好处是【内部类class.class】隐含地【持有】一个【它所在对象class的this引用】，可以通过【ReverseArrayCollection.this】引用到【它所在的集合】。

上述代码实现的逻辑非常简单，

但是实际应用时，如果考虑到【多线程访问】，当【一个线程】正在迭代【某个集合】，而【另一个线程】修改了【集合的内容】时，是否能【继续安全地迭代】，还是【抛出ConcurrentModificationException】，就需要更仔细地设计。


==================================================================


#	练习

使用Iterator模式实现集合的倒序遍历  */





/*==============================================================

#	----- 迭代器 Iterator の 小结 -----

1. 【Iterator模式】常用于【遍历集合】，它允许【集合】提供一个【统一的Iterator接口】来【遍历元素】，同时保证【调用者】对【集合内部的数据结构】一无所知，从而使得【调用者】总是以【相同的接口】遍历【各种不同类型的集合】。



-------------

内部实现模版: */
public class ReverseArrayCollection<T> implements Iteratble<T> {
	private T[] array;

	public ReverseArrayCollection(T... objs) {
		this.array = Arrays.copyOfRange(objs, 0, objs.length);
	}

	public Iterator<T> iterator() {
		return new ReverseIterator();
	}


	// class.class ReverseIterator
	class ReverseIterator implements Iterator<T> {
		int index;

		public ReverseIterator() {
			this.index = ReverseArrayCollection.this.array.length;
		}

		public boolean hasNext() {
			return index > 0;
		}

		public T next() {
			index--;
			return array[index];
		}
	}
}




